package com.linzelin.config;

import com.linzelin.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * @author 君未洋
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //继承了这个类之后就相当于这个类拥有所有的SpringSecurity所有的配置

    @Autowired
    private UserService userService;

    /**
     * 这个就是配置的一个将加密类加入到Spring的容器中的方式
     *
     * @return
     */
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 这个就是认证用户的来源了
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      /*  auth.inMemoryAuthentication()
                .withUser("admin")
                .password("{noop}123456")
                .roles("USER");
            //注意这里的用户角色不能使用ROLE开头,不然会报错*/

        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }

    /**
     * 配置SpringSecurity基本配置
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /*这里就是配置基本的登录页面,角色,登录相关的提交等等等*/
        http.authorizeRequests()
                .antMatchers("/login.html", "/failer.jsp", "/css/**", "/img/**", "/plugins/**").permitAll()
                .antMatchers("/**").hasAnyRole("USER", "SUPER", "PRODUCT")
                .anyRequest()
                .authenticated()
                //这里就代表/**下的资源只有在认证通过之后才能访问到
                .and()
                //这里的and是表示新的一个配置的开始
                .formLogin().loginPage("/toLogin")
                //这个是配置的登录的页面
                .loginProcessingUrl("/login")
                //这个是配置的对应的登录提交的请求提交
                .defaultSuccessUrl("/index.html")
                //    .successForwardUrl("/index.html")
                //配置登录成功后跳转的页面
                .failureForwardUrl("/failer.html")
                //登录失败后跳转页面
                .permitAll();
        //释放掉处理配置的这些基本页面
        /*配置下注销按钮*/
        http.logout().logoutUrl("/logout")
                .logoutSuccessUrl("/login.html")
                .invalidateHttpSession(true)
                //这个就是配置的是否清空session
                .permitAll();
        //这里还要再配置对应的拦截要重新配置
        http.csrf().disable();
        //关闭csrf
    }
}
